; files.asm
; file related routines

	.include "vicrom.inc"
	.include "string.inc"

	MAX_FILES = 16	; kernel limit is 10 ($A)

	.export open
	.export close
	.export getc
	.export putc
	.export fstatus
	.export gets

	.segment "ZEROPAGE"

fwreg0:
fbreg0:		.res 1
fbreg1:		.res 1

	.segment "RODATA"
	
bitmask:	.byte $80, $40, $20, $10, $08, $04, $02, $01
bitblank:	.byte $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F

	.segment "DATA"

filesused:	.byte 1
			.repeat ((MAX_FILES - 7) / 8) - 1
			.byte 0
			.endrep
			
fout:		.byte 0		; active file no (output)
fin:		.byte 0		; active file no (input)

tmplo:		.res 1
tmphi:		.res 1

	.segment "CODE"

;
;	public routines
;	Carry Flag indicates error (C=0 .. ok)
;

open:		; A/X ... ptr to <device:byte>,<channel:byte>,<namelength:byte>,<name>
			; -> A .. file no (0 .. error (C=1))
			sta fwreg0
			stx fwreg0+1
			clc
			adc #3
			sta tmplo
			txa
			adc #0
			sta tmphi
			ldy #2
			lda (fwreg0), y
			ldx tmplo
			ldy tmphi
			jsr SETNAM
			jsr allocfn
			beq @done
			pha
			ldy #0
			lda (fwreg0), y
			tax
			ldy #1
			lda (fwreg0), y
			tay
			pla
			pha
			jsr SETLFS
			jsr OPEN
			pla
@done:		rts

close:		; A .. fileno
			; -> error (Carry)
			pha
			jsr freefn
			pla
			jsr CLOSE
			rts
			
getc:		; A .. fileno
			; -> A .. byte read
			; -> error (Carry)
			jsr setin
			bcs @gfail
			jsr BASIN
@gfail:		rts
			
putc:		; A .. fileno (unchanged), X .. byte to write
			; -> error (Carry)
			jsr setout
			bcs @pfail
			pha
			txa
			jsr BSOUT
			pla
@pfail:		rts

fstatus:	; A .. filno (unchanged)
			; -> X .. error code
			pha
			jsr READSS
			tax
			pla
			rts

gets:		; A .. fileno
			; -> error (Carry)
			jsr setin
			bcs @gserr
			jsr sclear
@getslp:	jsr BASIN
			sta tmplo
			jsr READSS
			bne @gsend
			lda tmplo
			jsr saddch
			bcc @getslp
@gsend:		clc
@gserr:		rts

;
;	private routines
;

	.segment "CODE"

allocfn:	; -> A .. new LFN
			lda #0
			sta tmplo		; fileno
			ldx #0			; index
@nxt:		ldy #7			; shift counter
			lda filesused, x
@nxtinbyt:	lsr
			bcc @filenofnd
			inc tmplo
			dey
			bpl @nxtinbyt
			inx
			cmp #MAX_FILES / 8
			bne @nxt
			lda #0
			rts
@filenofnd:	; set bit
			lda filesused, x
			ora bitmask, y
			sta filesused, x
			; return result
			lda tmplo
			rts
			
freefn:		; A .. LFN
			tax
			and #7
			tay
			txa
			lsr
			lsr
			lsr
			tax
			lda filesused, x
			and bitblank, y
			sta filesused, x
			lda #0
			sta fin
			sta fout
			rts

isvalidfn:	; A .. LFN
			; -> C = 0 .. LFN is in use (aka valid).
			pha
			tax
			and #7
			eor #7
			tay
			txa
			lsr
			lsr
			lsr
			tax
			lda filesused, x
			and bitmask, y
			beq @notused
			clc
			.byte $24	; BIT ZP
@notused:	sec
			pla
			rts

setout:		; A .. LFN
			cmp fout
			beq @sogood
			tax
			sta fout
			jsr CKOUT
			bcs @sofail
@sogood:	clc
			rts
@sofail:	lda #0
			sta fout
			rts

setin:		; A .. LFN
			cmp fin
			beq @sigood
			tax
			sta fin
			jsr CHKIN
			bcs @sifail
@sigood:	clc
			rts
@sifail:	lda #0
			sta fin
			rts
			
